Classement de termes techniques

Classement des mots techniques - Implémentation (Partie 1)

Les types de données

Tous d'abord le type de données Tradln associé aux lignes récupérées du fichier texte en entrée.

data Tradln = Tradln  { lnCode    :: String -- Identifiant de la cellule (Automatique ou manuel)
                      , lnTradEn  :: String -- Le mot en Anglais
                      , lnTradFr  :: String -- Le mot en Français
                      , lnDom1    :: String -- Le domaine 1
                      , lnDom2    :: String -- Le domaine 2
                      , lnDom3    :: String -- Le domaine 3
                      , lnVersion :: Int    -- Le numéro de version
                      , lnOk      :: Bool   -- Intégration de la ligne ou non
                      } deriving (Eq)

Ce type contient les champs associés à une ligne de données sous la forme de chaîne de caractère String pour les mots et les domaines, un entier Int pour le numéro de version et un booléen Bool pour l'intégration de la ligne.

Ensuite le type Traduction contenant un groupe (cellule) de traduction.

data Traduction = Traduction { code   :: String        -- Identifiant de la cellule (Automatique ou manuel)
                             , lang   :: Lang          -- La langue de la cellule
                             , tradEn :: [TradLaTeXEn] -- Une liste de traductions en Anglais
                             , tradFr :: [TradLaTeXFr] -- Une liste de traductions en Français
                             , dom1   :: String        -- Le domaine 1
                             , dom2   :: String        -- Le domaine 2
                             , dom3   :: String        -- Le domaine 3
                             } deriving (Eq) 

Ce type contient les champs de type String, de type spécial [TradLaTeXEn] pour les traductions et de type Lang pour la langue dans laquelle s'effectue la traduction. Ce type Lang sert à définir la langue et peut valoir En (Anglais) ou Fr (Français):

data Lang = En | Fr deriving (Eq) 

et enfin les types [TradLaTeXFr] et [TradLaTeXEn] qui serviront à l'exportation des commandes LaTeX plus loin:

data TradLaTeXEn = TradLaTeXEn (String) deriving (Eq) 
data TradLaTeXFr = TradLaTeXFr (String) deriving (Eq)

Les fonctions de filtrage

Afin de filtrer les lignes de traduction, on utilise la fonction filter qui permet d'appliquer un critère à une liste et de retourner une liste qui vérifie ce critère. Pour définir ce critère, on peut utiliser plusieurs fonctionnalités qu'offre Haskell :

les fonctions anonymes : 

filtreOk lst = filter (\a -> (lnOk a) == True) lst

Avec Haskell le symbole \\ (backslash) avec -> permet de déclarer ce type de fonction. La fonction déclarée ici prend un argument a et retourne True si le code d'intégration est égal à True.

la composition de fonctions : 

filtreOk lst = filter((==True) . lnOk) lst

Avec Haskell, le point à la même signification qu'en mathématiques. C'est l'opérateur de composition de fonctions.

Ces deux écritures fonctionnent aussi bien l'une que l'autre

  • La fonction filtreOk permet de filtrer les lignes de la liste lst si lnOk est vrai (True).

    filtreOk :: [Tradln] -> [Tradln]
    filtreOk lst = filter ((==True) . lnOk) lst
    
  • La fonction filtreVer permet de filtrer les lignes de la liste lst dont le numéro de version est inférieur ou égale à ver

    filtreVer :: Int -> [Tradln] -> [Tradln] 
    filtreVer ver lst = filter ((<=ver) . lnVersion) lst
    
  • Les fonctions suivantes permettent de filtrer les listes ayant respectivement le même mot anglais, le même mot français et le même code de regroupement.

    filtreEn :: [Tradln] -> String -> [Tradln]
    filtreEn lst mot = filter ((==mot) . lnTradEn) lst 
    
    filtreFr :: [Tradln] -> String -> [Tradln] 
    filtreFr lst mot = filter ((==mot) . lnTradFr) lst 
    
    filtreCode :: [Tradln] -> String -> [Tradln] 
    filtreCode lst code = filter ((==code) . lnCode) lst
    
  • La fonction filtreDom permet de filtrer les lignes de la liste lst si l'un des domaines est égal à celui renseigné en paramètres. Pour effectuer le test logique, on pourrait créer une fonction spécifique du style :

    test dom ln = dom == lnDom1 ln || dom == lnDom2 ln || dom == lnDom3 ln 
    

    et l'utiliser comme filtre de cette façon :

    filtreDom lst dom = filter (test dom) lst 
    

    mais on peut aussi condenser l'écriture sur une ligne en utilisant une fonction anonyme.

    filtreDom :: [Tradln] -> String -> [Tradln] 
    filtreDom lst dom = filter (\a -> dom == lnDom1 a || dom == lnDom2 a || dom == lnDom3 a) lst 
    

    Cette fonction prend comme argument a, une ligne de traduction, et la vérifie si le domaine 1 de a est égale à dom ou si le domaine 2 de a est égale à dom ou si le domaine 3 de a est égale à dom.

Les fonctions de tri

La fonction Haskell de base pour trier une liste est sort. Mais attention, cette fonction bien qu'elle puisse être utilisée sur des types contenant des champs va effectuer un tri sur tous les champs les uns après les autres (tri selon la version, puis tri selon les domaines, puis tri selon les mots, etc…). Or ce n'est pas ce que l'on veut ici. Il est nécessaire d'imposer le tri suivant un seul champ. Pour cela, il y a la fonction sortBy (tri selon…). Pour l'utiliser, il faut lui fournir en premier argument une fonction effectuant la comparaison.

triEn :: [Tradln] -> [Tradln] 
triEn lst = sortBy (on compare lnTradEn) lst
 
triFr :: [Tradln] -> [Tradln] 
triFr lst = sortBy (on compare lnTradFr) lst